#include "ui_view.h"
#include "ui_error.h"
#include "ui_painter.h"
#include "ui_message_server.h"
#include "ui_application.h"
#include "ui_std_ex.h"
#include <iostream>
using namespace std;

namespace UI
{

UI_View* UI_View::m_pInstance = 0;

UI_View* UI_View::GetView(void){
	if (!m_pInstance)
	{
		throw(UI_Ex_App("Cannot find view."));
	}
	return m_pInstance;
}

UI_View::UI_View() :
	UI_Window(UI_Rect(0,0,UI_Application::Instance()->GetAppScreenWidth(),UI_Application::Instance()->GetAppScreenHeight()), 0),
	m_pFloatingWindow(0),
	m_pScreenSurface(0)
{
	if (m_pInstance)
	{
		throw(UI_Ex_App("Cannot have more than one view at a time!"));
	}
	m_pInstance = this;

	UI_MessageServer::Instance().RegisterMessageClient(this, UI_Message::APP_PAINT);
	//UI_MessageServer::Instance().RegisterMessageClient(this, UI_Message::USER,UI_MessageServer::PRIORITY_LAST);
	//UI_MessageServer::Instance().RegisterMessageClient(this, UI_Message::APP_DESTROY_FRAME, UI_MessageServer::PRIORITY_FIRST);
	//UI_MessageServer::Instance().RegisterMessageClient(this, UI_Message::MOUSE_BUTTONDOWN, UI_MessageServer::PRIORITY_FIRST);
	//UI_MessageServer::Instance().RegisterMessageClient(this, UI_Message::MOUSE_BUTTONUP, UI_MessageServer::PRIORITY_FIRST);

	SetWindowRect(UI_Rect(0,0,UI_Application::Instance()->GetAppScreenWidth(),UI_Application::Instance()->GetAppScreenHeight()));
	UI_Application::Instance()->GetApplicationLog().AddLogEntry("Created new CView : ", APP_LOG_INFO);
	Draw();
}


UI_View::~UI_View(void)
{
	if (m_pInstance == this)
	{
		m_pInstance = 0;
	}
}


void UI_View::SetWindowRect(const UI_Rect& WindowRect)
{
	UI_Window::SetWindowRect(WindowRect);
	m_ClientRect = UI_Rect(0, 0, m_WindowRect.Width(), m_WindowRect.Height());

	m_pScreenSurface = UI_Application::Instance()->GetAppScreen();
}

bool UI_View::HandleMessage(UI_Message* pMessage)
{
	bool bHandled = false;

	if (pMessage)
	{
		switch(pMessage->MessageType())
		{
		case UI_Message::APP_PAINT :
		{
			if (pMessage->Destination() == this || pMessage->Destination() == 0)
			{
				PaintToSurface(m_pScreenSurface,UI_Point(0, 0));
				SDL_UpdateRect(m_pScreenSurface, 0, 0, 0, 0);
				bHandled = true;
			}
			break;
		}
		case UI_Message::MOUSE_BUTTONDOWN:
		{
			UI_MouseMessage* pMouseMessage = dynamic_cast<UI_MouseMessage*>(pMessage);
			if (pMouseMessage && m_WindowRect.HitTest(pMouseMessage->Point) == UI_Rect::RELPOS_INSIDE)
			{
				if (!m_pFloatingWindow || !m_pFloatingWindow->OnMouseButtonDown(pMouseMessage->Point, pMouseMessage->Button))
				{
					if (pMouseMessage->Destination() == 0)
					{
						OnMouseButtonDown(pMouseMessage->Point, pMouseMessage->Button);
					}
					else if (dynamic_cast<const UI_Window*>(pMouseMessage->Destination()))
					{
						const_cast<UI_Window*>(static_cast<const UI_Window*>(pMouseMessage->Destination()))->
							OnMouseButtonDown(pMouseMessage->Point, pMouseMessage->Button);
					}
				}
			}
			break;
		}
		case UI_Message::MOUSE_BUTTONUP:
		{
			UI_MouseMessage* pMouseMessage = dynamic_cast<UI_MouseMessage*>(pMessage);
			if (pMouseMessage && m_WindowRect.HitTest(pMouseMessage->Point) == UI_Rect::RELPOS_INSIDE)
			{
				if (!m_pFloatingWindow || !m_pFloatingWindow->OnMouseButtonUp(pMouseMessage->Point, pMouseMessage->Button))
				{
					if (pMouseMessage->Destination() == 0)
					{
						OnMouseButtonUp(pMouseMessage->Point, pMouseMessage->Button);
					}
					else if (dynamic_cast<const UI_Window*>(pMouseMessage->Destination()))
					{
						const_cast<UI_Window*>(static_cast<const UI_Window*>(pMouseMessage->Destination()))->
							OnMouseButtonUp(pMouseMessage->Point, pMouseMessage->Button);
					}
				}
			}
			break;
		}
		default :
			bHandled = UI_Window::HandleMessage(pMessage);
			break;
		}
	}

	return bHandled;
}

}


